import { auth } from '@clerk/nextjs/server';
import { notFound, redirect } from 'next/navigation';
import { validate as uuidValidate } from 'uuid';

import { Clip } from '@/state/clipStore';
import { PersonaMetadata } from '@/state/personaStore';

import SongPage from './SongPage';
import { generateMetadata, getClip, getPersona } from './metadata';

type Props = {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
};

export { generateMetadata };

export default async function SongPageDefine(props: Props) {
  const params = await props.params;
  const clipId = params.slug;
  const resolvedSearchParams = await props.searchParams;

  // Attempt to rescue bad URLs if the problem is that there is extra junk after the UUID
  if (!uuidValidate(clipId)) {
    if (uuidValidate(clipId.substring(0, 36))) {
      console.error(
        `Clip ID ${clipId} looks like a malformed ID, attempting to redirect to ${clipId.substring(0, 36)}`
      );
      redirect(
        `/song/${clipId.substring(0, 36)}${
          Object.keys(resolvedSearchParams).length > 0
            ? `?${new URLSearchParams(
                resolvedSearchParams as Record<string, string>
              ).toString()}`
            : ''
        }`
      );
    } else {
      notFound();
    }
  }

  const timeStr = resolvedSearchParams.time;

  const timeInt = timeStr ? parseInt(timeStr as string) : undefined;

  let clip: Clip;
  let persona: PersonaMetadata | null = null;
  let clipHistoryIds: string[] = [];

  const { getToken } = await auth();
  let accessToken = null;
  try {
    accessToken = await getToken();
  } catch (e) {
    console.log(e);
  }

  try {
    clip = await getClip(clipId, accessToken);

    // is_hidden is for moderated clips, missing from schema currently
    if (!clip || (clip as any).is_hidden) {
      return (
        <div className='flex h-screen w-screen items-center justify-center text-center font-sans'>
          Clip not found
        </div>
      );
    }

    if (clip?.metadata?.history?.length) {
      clipHistoryIds = clip.metadata.history
        .filter((h: any) => h.id)
        .map((h: any) => h.id);
    }

    try {
      if (clip?.metadata?.persona_id) {
        persona = await getPersona(clip.metadata.persona_id, accessToken);
      }
    } catch (error) {
      console.error('Error fetching clip metadata:', error);
    }
  } catch (e) {
    console.log('Failed to load clip', e);
    notFound();
  }

  // prevent visiting song page if preview_seconds is 0
  if (clip.preview_seconds === 0) {
    return redirect('/');
  }
  return (
    <SongPage
      clip={clip}
      persona={persona}
      clipHistoryIds={clipHistoryIds}
      time={timeInt}
    />
  );
}
